using System;
using System.Data;
using System.Configuration;
using System.Net;
using System.Net.Mail;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Threading;
using System.Text;

namespace Pitoshka.Tools.Helpers
{
	public class MailTemplate : IDisposable
	{
		#region Static properties
		private static Encoding _DefaultEncoding;
		public static Encoding DefaultEncoding
		{
			get { return _DefaultEncoding; }
			set { _DefaultEncoding = value; }
		}
		#endregion

		#region Properties
		private MailMessage _Message = new MailMessage();
		public MailMessage Message
		{
			get { return _Message; }
			set { _Message = value; }
		}

		private Encoding _MessageEncoding = DefaultEncoding;
		public Encoding MessageEncoding
		{
			get { return _MessageEncoding; }
		}

		private string _SubjectTemplate;
		public string SubjectTemplate
		{
			get { return _SubjectTemplate; }
			set { _SubjectTemplate = value; }
		}

		private string _BodyTemplate;
		public string BodyTemplate
		{
			get { return _BodyTemplate; }
			set { _BodyTemplate = value; }
		}

		private string _HtmlBodyTemplate;
		public string HtmlBodyTemplate
		{
			get { return _HtmlBodyTemplate; }
			set { _HtmlBodyTemplate = value; }
		}

		private List<object> _Parameters = new List<object>();
		public List<object> Parameters
		{
			get { return _Parameters; }
			set { _Parameters = value; }
		}

		private Dictionary<string, object> _ParametersDic = new Dictionary<string, object>();
		public Dictionary<string, object> ParametersDic
		{
			get { return _ParametersDic; }
			set { _ParametersDic = value; }
		}

		private List<Type> _SupportedTypes = new List<Type>();
		public List<Type> SupportedTypes
		{
			get { return _SupportedTypes; }
			set { _SupportedTypes = value; }
		}
		#endregion Properties

		#region Constructors
		public MailTemplate()
		{
		}
		public MailTemplate(string templateName)
		{
			this.LoadTemplate(templateName);
		}
		#endregion Constructors

		#region Public methods
		public void LoadTemplate(string templateName)
		{
			this.LoadTemplate(templateName, DefaultEncoding);
		}
		public void LoadTemplate(string templateName, Encoding enc)
		{
			Message.BodyEncoding = enc;

			XmlDocument xDoc = new XmlDocument();
			xDoc.Load(this.GetCultureDependedTemplate(templateName));

			// Subject
			this.SubjectTemplate = xDoc.SelectSingleNode("//Subject").InnerText;


			// From
			if (!string.IsNullOrEmpty(xDoc.SelectSingleNode("//From").Attributes["Email"].Value))
			{
				Message.From = new MailAddress(
					xDoc.SelectSingleNode("//From").Attributes["Email"].Value
					, xDoc.SelectSingleNode("//From").Attributes["Name"].Value
					, enc);
				Message.Sender = Message.From;
			}


			// BCC copies
			XmlNodeList bccNodes = xDoc.SelectNodes("//Bcc");
			foreach (XmlNode bccNode in bccNodes)
			{
				string email = bccNode.Attributes["Email"].Value;
				string name = bccNode.Attributes["Name"].Value;

				this.Message.Bcc.Add(new MailAddress(email, name, enc));
			}


			// Body
			if (xDoc.SelectSingleNode("//Body") != null)
				this.BodyTemplate = xDoc.SelectSingleNode("//Body").InnerText;


			// Html Body
			if (xDoc.SelectSingleNode("//HtmlBody") != null)
				this.HtmlBodyTemplate = xDoc.SelectSingleNode("//HtmlBody").InnerText;
			
		}
		public void SendEmail()
		{
			// Subject
			Message.SubjectEncoding = this.MessageEncoding;
			Message.Subject = ParseTemplate(SubjectTemplate);

			// Body
			Message.BodyEncoding = this.MessageEncoding;
			string bodyHtml = ParseTemplate(HtmlBodyTemplate);
			if (!String.IsNullOrEmpty(bodyHtml))
			{
				Message.IsBodyHtml = true;
				Message.Body = bodyHtml;
			}
			else
			{
				Message.IsBodyHtml = true;
				Message.Body = ParseTemplate(BodyTemplate);
			}

			
			

			// Sending email
			SmtpClient smtp = new SmtpClient();

			smtp.Host = MailHelper.SMTP;
			smtp.Port = MailHelper.Port;

			if (!string.IsNullOrEmpty(MailHelper.SmtpUserName) && !string.IsNullOrEmpty(MailHelper.SmtpUserPassword))
				smtp.Credentials = new NetworkCredential(MailHelper.SmtpUserName, MailHelper.SmtpUserPassword);

			smtp.Send(_Message);
		}
		#endregion Public methods

		#region Private methods
		private string ParseTemplate(string template)
		{
			string result = template;

			foreach (object obj in Parameters)
			{
				result = TemplateHelper.FillTemplate(result, obj, SupportedTypes);
			}

			foreach (KeyValuePair<string, object> pair in this.ParametersDic)
			{
				result = TemplateHelper.FillTemplate(result, pair.Key, pair.Value);
			}

			return result;
		}
		private string GetCultureDependedTemplate(string templateFileName)
		{
			string ext = Path.GetExtension(templateFileName);
			string fileName = Path.GetFileNameWithoutExtension(templateFileName);
			string dir = Path.GetDirectoryName(templateFileName);

			string result = templateFileName;

			string FullCultureTemplate = Path.Combine(dir, fileName + "." + Thread.CurrentThread.CurrentUICulture.Name + ext);
			string MainCultureTemplate = Path.Combine(dir, fileName + "." + Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName + ext);

			if (File.Exists(FullCultureTemplate))
				result = FullCultureTemplate;
			else if (File.Exists(MainCultureTemplate))
				result = MainCultureTemplate;

			return result;
		}
		#endregion Private methods

		#region IDisposable Members
		public void Dispose()
		{
			_Message.Dispose();
		}
		#endregion
	}
}
